﻿using HZH_Controls;
using NDK.Frm;
using NDK.Module.Model;
using NDK.Motion.Sys;
using Newtonsoft.Json;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Threading;
using System.Windows.Forms;

namespace NDK.Module.StationLogic
{
    public class SunWayOEETime
    {
        /// <summary>
        /// 计数时间
        /// </summary>
        public string Time { get; set; }

        /// <summary>
        /// 性能稼动率
        /// </summary>
        public string PAR { get; set; }

        /// <summary>
        /// 运行时长
        /// </summary>
        public int RunningTime { get; set; }

        /// <summary>
        /// 异常时长
        /// </summary>
        public int AlarmTime { get; set; }

        /// <summary>
        /// 待料时长
        /// </summary>
        public int WaitTime { get; set; }

        /// <summary>
        /// 计划停机时长
        /// </summary>
        public int PlanTime { get; set; }

        /// <summary>
        /// DOE时长
        /// </summary>
        public int DOETime { get; set; }

        /// <summary>
        /// 理论CT
        /// </summary>
        public double CT { get; set; }

        [JsonIgnore]
        public int TotalTime { get; set; } = 7200;

    }

    public class SunWayOEETimeMethod
    {
        protected readonly string OEEFilePath = $"{Environment.CurrentDirectory}\\Config\\SunWayOEE.json";

        private int CurRow;
        private bool IsFirst;

        private DateTime STime { get; set; }
        public OEESSTATUS Status { get; set; }
        public ObservableCollection<SunWayOEETime> OEEs { get; set; } = null;

        public SunWayOEETimeMethod()
        {
            CurRow = -1;
            IsFirst = false;
            Frm_Home.Instance.DGVOEE.DataSource = Init();
            Frm_Home.Instance.DGVOEE.Columns[nameof(SunWayOEETime.TotalTime)].Visible = false;
            MachineStatusManager.PropertyChanged += MachineStatusManager_PropertyChanged;
        }

        private void MachineStatusManager_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName != "Running")
            {
                if (Status != OEESSTATUS.ALARM)
                {
                    ChangeStatus(OEESSTATUS.ALARM);
                }
            }
            else
            {
                if (Status != OEESSTATUS.RUN)
                {
                    ChangeStatus(OEESSTATUS.RUN);
                }
            }
            if (e.PropertyName == "Running")
            {
                double waitct = Station_上料定位.Instance.WaitCT.ToDouble();
                if(waitct >2)
                {
                    ChangeStatus(OEESSTATUS.WAIT);
                }
            }

        }

        private ObservableCollection<SunWayOEETime> Init()
        {
            STime = DateTime.Now;
            Status = OEESSTATUS.WAIT;
            if (File.Exists(OEEFilePath))
            {
                OEEs = JsonConvert.DeserializeObject<ObservableCollection<SunWayOEETime>>(File.ReadAllText(OEEFilePath));
            }
            if (OEEs == null)
            {
                OEEs = new ObservableCollection<SunWayOEETime>();
                for (int i = 0; i < 12; i++)
                {
                    OEEs.Add(new SunWayOEETime() { Time = $"{(i * 2).ToString().PadLeft(2, '0')}:00 - {((i * 2) + 2).ToString().PadLeft(2, '0')}:00" });
                }
            }
            return OEEs;
        }

        public void ChangeStatus(OEESSTATUS status)
        {
            RefreshOEE(STime, DateTime.Now, Status, Frm_Home.Instance.DGVOEE);
            STime = DateTime.Now;
            Status = status;
        }

        private void RefreshOEE(DateTime sTime, DateTime eTime, OEESSTATUS status, DataGridView dgv)
        {
            int Row1 = 0, Row2 = 0;
            int TomTime1, TomTime2;
            string fieldName = string.Empty;
            TimeSpan timeSpan1, timeSpan2;
            Row1 = (int)(Math.Ceiling((double)(sTime.Hour / 2)));
            Row2 = (int)(Math.Ceiling((double)(eTime.Hour / 2)));
            if (!IsFirst) { CurRow = Row1; IsFirst = true; }
            if (Row2 == CurRow)
            {
                timeSpan1 = eTime - sTime;
                timeSpan2 = TimeSpan.Zero;
            }
            else
            {
                CurRow = Row2;
                DateTime time = new DateTime(eTime.Year, eTime.Month, eTime.Day, eTime.Hour, 0, 0);
                timeSpan1 = time - sTime;
                timeSpan2 = eTime - time;
                OEEs[Row2].RunningTime = 0;
                OEEs[Row2].AlarmTime = 0;
                OEEs[Row2].WaitTime = 0;
                OEEs[Row2].PlanTime = 0;
                OEEs[Row2].DOETime = 0;
            }

            switch (status)
            {
                case OEESSTATUS.RUN:
                    fieldName = nameof(SunWayOEETime.RunningTime);
                    break;
                case OEESSTATUS.ALARM:
                    fieldName = nameof(SunWayOEETime.AlarmTime);
                    break;
                case OEESSTATUS.WAIT:
                    fieldName = nameof(SunWayOEETime.WaitTime);
                    break;
                case OEESSTATUS.DOE:
                    fieldName = nameof(SunWayOEETime.DOETime);
                    break;
                case OEESSTATUS.PLAN:
                    fieldName = nameof(SunWayOEETime.PlanTime);
                    break;
                default:
                    break;
            }
            var field1 = OEEs[Row1].GetType().GetProperty(fieldName);
            var field2 = OEEs[Row2].GetType().GetProperty(fieldName);
            TomTime1 = (int)field1.GetValue(OEEs[Row1]);
            TomTime2 = (int)field2.GetValue(OEEs[Row2]);
            if (timeSpan2 == TimeSpan.Zero)
            {
                field1.SetValue(OEEs[Row1], TomTime1 += (int)Math.Floor(timeSpan1.TotalSeconds));
                OEEs[Row1].PAR = $" {Math.Round(OEEs[Row1].RunningTime / (eTime - DateTime.Parse(OEEs[Row1].Time.Split('-')[0])).TotalSeconds * 100, 2)}%";
            }
            else
            {
                field1.SetValue(OEEs[Row1], TomTime1 += (int)Math.Floor(timeSpan1.TotalSeconds));
                field2.SetValue(OEEs[Row2], TomTime2 += (int)Math.Floor(timeSpan2.TotalSeconds));
                int alltime = OEEs[Row1].RunningTime + OEEs[Row1].WaitTime + OEEs[Row1].PlanTime + OEEs[Row1].DOETime;
                OEEs[Row1].AlarmTime = OEEs[Row1].TotalTime - alltime;
                OEEs[Row1].PAR = $"{Math.Round((double)OEEs[Row1].RunningTime / 7200 * 100, 2)}%";
                OEEs[Row2].PAR = $"{Math.Round(OEEs[Row2].RunningTime / timeSpan2.TotalSeconds * 100, 2)}%";
            }
            dgv.Refresh();
            string str = JsonConvert.SerializeObject(OEEs, Formatting.Indented);
            File.WriteAllText(OEEFilePath, str);
        }
    }

    public enum OEESSTATUS
    {
        RUN,
        ALARM,
        WAIT,
        DOE,
        PLAN
    }
}
